1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module sourceview.SearchContext; 26 27 private import gio.AsyncResultIF; 28 private import gio.Cancellable; 29 private import glib.ConstructionException; 30 private import glib.ErrorG; 31 private import glib.GException; 32 private import glib.MemorySlice; 33 private import glib.Str; 34 private import gobject.ObjectG; 35 private import gtk.TextIter; 36 private import sourceview.Buffer; 37 private import sourceview.SearchSettings; 38 private import sourceview.Style; 39 private import sourceview.c.functions; 40 public import sourceview.c.types; 41 42 43 /** 44 * Search context. 45 * 46 * A `GtkSourceSearchContext` is used for the search and replace in a 47 * [class@Buffer]. The search settings are represented by a 48 * [class@SearchSettings] object. There can be a many-to-many relationship 49 * between buffers and search settings, with the search contexts in-between: a 50 * search settings object can be shared between several search contexts; and a 51 * buffer can contain several search contexts at the same time. 52 * 53 * The total number of search occurrences can be retrieved with 54 * [method@SearchContext.get_occurrences_count]. To know the position of a 55 * certain match, use [method@SearchContext.get_occurrence_position]. 56 * 57 * The buffer is scanned asynchronously, so it doesn't block the user interface. 58 * For each search, the buffer is scanned at most once. After that, navigating 59 * through the occurrences doesn't require to re-scan the buffer entirely. 60 * 61 * To search forward, use [method@SearchContext.forward] or 62 * [method@SearchContext.forward_async] for the asynchronous version. 63 * The backward search is done similarly. To replace a search match, or all 64 * matches, use [method@SearchContext.replace] and 65 * [method@SearchContext.replace_all]. 66 * 67 * The search occurrences are highlighted by default. To disable it, use 68 * [method@SearchContext.set_highlight]. You can enable the search 69 * highlighting for several `GtkSourceSearchContext`s attached to the 70 * same buffer. Moreover, each of those `GtkSourceSearchContext`s can 71 * have a different text style associated. Use 72 * [method@SearchContext.set_match_style] to specify the [class@Style] 73 * to apply on search matches. 74 * 75 * Note that the [property@SearchContext:highlight] and 76 * [property@SearchContext:match-style] properties are in the 77 * `GtkSourceSearchContext` class, not [class@SearchSettings]. Appearance 78 * settings should be tied to one, and only one buffer, as different buffers can 79 * have different style scheme associated (a [class@SearchSettings] object 80 * can be bound indirectly to several buffers). 81 * 82 * The concept of "current match" doesn't exist yet. A way to highlight 83 * differently the current match is to select it. 84 * 85 * A search occurrence's position doesn't depend on the cursor position or other 86 * parameters. Take for instance the buffer "aaaa" with the search text "aa". 87 * The two occurrences are at positions [0:2] and [2:4]. If you begin to search 88 * at position 1, you will get the occurrence [2:4], not [1:3]. This is a 89 * prerequisite for regular expression searches. The pattern ".*" matches the 90 * entire line. If the cursor is at the middle of the line, you don't want the 91 * rest of the line as the occurrence, you want an entire line. (As a side note, 92 * regular expression searches can also match multiple lines.) 93 * 94 * In the GtkSourceView source code, there is an example of how to use the 95 * search and replace API: see the tests/test-search.c file. It is a mini 96 * application for the search and replace, with a basic user interface. 97 */ 98 public class SearchContext : ObjectG 99 { 100 /** the main Gtk struct */ 101 protected GtkSourceSearchContext* gtkSourceSearchContext; 102 103 /** Get the main Gtk struct */ 104 public GtkSourceSearchContext* getSearchContextStruct(bool transferOwnership = false) 105 { 106 if (transferOwnership) 107 ownedRef = false; 108 return gtkSourceSearchContext; 109 } 110 111 /** the main Gtk struct as a void* */ 112 protected override void* getStruct() 113 { 114 return cast(void*)gtkSourceSearchContext; 115 } 116 117 /** 118 * Sets our main struct and passes it to the parent class. 119 */ 120 public this (GtkSourceSearchContext* gtkSourceSearchContext, bool ownedRef = false) 121 { 122 this.gtkSourceSearchContext = gtkSourceSearchContext; 123 super(cast(GObject*)gtkSourceSearchContext, ownedRef); 124 } 125 126 127 /** */ 128 public static GType getType() 129 { 130 return gtk_source_search_context_get_type(); 131 } 132 133 /** 134 * Creates a new search context, associated with @buffer, and customized with 135 * @settings. 136 * 137 * If @settings is %NULL, a new [class@SearchSettings] object will 138 * be created, that you can retrieve with [method@SearchContext.get_settings]. 139 * 140 * Params: 141 * buffer = a #GtkSourceBuffer. 142 * settings = a #GtkSourceSearchSettings, or %NULL. 143 * 144 * Returns: a new search context. 145 * 146 * Throws: ConstructionException GTK+ fails to create the object. 147 */ 148 public this(Buffer buffer, SearchSettings settings) 149 { 150 auto __p = gtk_source_search_context_new((buffer is null) ? null : buffer.getBufferStruct(), (settings is null) ? null : settings.getSearchSettingsStruct()); 151 152 if(__p is null) 153 { 154 throw new ConstructionException("null returned by new"); 155 } 156 157 this(cast(GtkSourceSearchContext*) __p, true); 158 } 159 160 /** 161 * Synchronous backward search. 162 * 163 * It is recommended to use the asynchronous functions instead, to not block the user interface. 164 * However, if you are sure that the @buffer is small, this function is more convenient to use. 165 * 166 * If the [property@SearchSettings:wrap-around] property is %FALSE, this function 167 * doesn't try to wrap around. 168 * 169 * The @has_wrapped_around out parameter is set independently of whether a match 170 * is found. So if this function returns %FALSE, @has_wrapped_around will have 171 * the same value as the [property@SearchSettings:wrap-around] property. 172 * 173 * Params: 174 * iter = start of search. 175 * matchStart = return location for start of match, or %NULL. 176 * matchEnd = return location for end of match, or %NULL. 177 * hasWrappedAround = return location to know whether the 178 * search has wrapped around, or %NULL. 179 * 180 * Returns: whether a match was found. 181 */ 182 public bool backward(TextIter iter, out TextIter matchStart, out TextIter matchEnd, out bool hasWrappedAround) 183 { 184 GtkTextIter* outmatchStart = sliceNew!GtkTextIter(); 185 GtkTextIter* outmatchEnd = sliceNew!GtkTextIter(); 186 int outhasWrappedAround; 187 188 auto __p = gtk_source_search_context_backward(gtkSourceSearchContext, (iter is null) ? null : iter.getTextIterStruct(), outmatchStart, outmatchEnd, &outhasWrappedAround) != 0; 189 190 matchStart = ObjectG.getDObject!(TextIter)(outmatchStart, true); 191 matchEnd = ObjectG.getDObject!(TextIter)(outmatchEnd, true); 192 hasWrappedAround = (outhasWrappedAround == 1); 193 194 return __p; 195 } 196 197 /** 198 * The asynchronous version of [method@SearchContext.backward]. 199 * 200 * See the [iface@Gio.AsyncResult] documentation to know how to use this function. 201 * 202 * If the operation is cancelled, the @callback will only be called if 203 * @cancellable was not %NULL. The method takes 204 * ownership of @cancellable, so you can unref it after calling this function. 205 * 206 * Params: 207 * iter = start of search. 208 * cancellable = a #GCancellable, or %NULL. 209 * callback = a #GAsyncReadyCallback to call when the operation is finished. 210 * userData = the data to pass to the @callback function. 211 */ 212 public void backwardAsync(TextIter iter, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 213 { 214 gtk_source_search_context_backward_async(gtkSourceSearchContext, (iter is null) ? null : iter.getTextIterStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 215 } 216 217 /** 218 * Finishes a backward search started with 219 * [method@SearchContext.backward_async]. 220 * 221 * See the documentation of [method@SearchContext.backward] for more 222 * details. 223 * 224 * Params: 225 * result = a #GAsyncResult. 226 * matchStart = return location for start of match, or %NULL. 227 * matchEnd = return location for end of match, or %NULL. 228 * hasWrappedAround = return location to know whether the 229 * search has wrapped around, or %NULL. 230 * 231 * Returns: whether a match was found. 232 * 233 * Throws: GException on failure. 234 */ 235 public bool backwardFinish(AsyncResultIF result, out TextIter matchStart, out TextIter matchEnd, out bool hasWrappedAround) 236 { 237 GtkTextIter* outmatchStart = sliceNew!GtkTextIter(); 238 GtkTextIter* outmatchEnd = sliceNew!GtkTextIter(); 239 int outhasWrappedAround; 240 GError* err = null; 241 242 auto __p = gtk_source_search_context_backward_finish(gtkSourceSearchContext, (result is null) ? null : result.getAsyncResultStruct(), outmatchStart, outmatchEnd, &outhasWrappedAround, &err) != 0; 243 244 if (err !is null) 245 { 246 throw new GException( new ErrorG(err) ); 247 } 248 249 matchStart = ObjectG.getDObject!(TextIter)(outmatchStart, true); 250 matchEnd = ObjectG.getDObject!(TextIter)(outmatchEnd, true); 251 hasWrappedAround = (outhasWrappedAround == 1); 252 253 return __p; 254 } 255 256 /** 257 * Synchronous forward search. 258 * 259 * It is recommended to use the asynchronous functions instead, to not block the user interface. 260 * However, if you are sure that the @buffer is small, this function is more convenient to use. 261 * 262 * If the [property@SearchSettings:wrap-around] property is %FALSE, this function 263 * doesn't try to wrap around. 264 * 265 * The @has_wrapped_around out parameter is set independently of whether a match 266 * is found. So if this function returns %FALSE, @has_wrapped_around will have 267 * the same value as the [property@SearchSettings:wrap-around] property. 268 * 269 * Params: 270 * iter = start of search. 271 * matchStart = return location for start of match, or %NULL. 272 * matchEnd = return location for end of match, or %NULL. 273 * hasWrappedAround = return location to know whether the 274 * search has wrapped around, or %NULL. 275 * 276 * Returns: whether a match was found. 277 */ 278 public bool forward(TextIter iter, out TextIter matchStart, out TextIter matchEnd, out bool hasWrappedAround) 279 { 280 GtkTextIter* outmatchStart = sliceNew!GtkTextIter(); 281 GtkTextIter* outmatchEnd = sliceNew!GtkTextIter(); 282 int outhasWrappedAround; 283 284 auto __p = gtk_source_search_context_forward(gtkSourceSearchContext, (iter is null) ? null : iter.getTextIterStruct(), outmatchStart, outmatchEnd, &outhasWrappedAround) != 0; 285 286 matchStart = ObjectG.getDObject!(TextIter)(outmatchStart, true); 287 matchEnd = ObjectG.getDObject!(TextIter)(outmatchEnd, true); 288 hasWrappedAround = (outhasWrappedAround == 1); 289 290 return __p; 291 } 292 293 /** 294 * The asynchronous version of [method@SearchContext.forward]. 295 * 296 * See the [iface@Gio.AsyncResult] documentation to know how to use this function. 297 * 298 * If the operation is cancelled, the @callback will only be called if 299 * @cancellable was not %NULL. The method takes 300 * ownership of @cancellable, so you can unref it after calling this function. 301 * 302 * Params: 303 * iter = start of search. 304 * cancellable = a #GCancellable, or %NULL. 305 * callback = a #GAsyncReadyCallback to call when the operation is finished. 306 * userData = the data to pass to the @callback function. 307 */ 308 public void forwardAsync(TextIter iter, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 309 { 310 gtk_source_search_context_forward_async(gtkSourceSearchContext, (iter is null) ? null : iter.getTextIterStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 311 } 312 313 /** 314 * Finishes a forward search started with [method@SearchContext.forward_async]. 315 * 316 * See the documentation of [method@SearchContext.forward] for more 317 * details. 318 * 319 * Params: 320 * result = a #GAsyncResult. 321 * matchStart = return location for start of match, or %NULL. 322 * matchEnd = return location for end of match, or %NULL. 323 * hasWrappedAround = return location to know whether the 324 * search has wrapped around, or %NULL. 325 * 326 * Returns: whether a match was found. 327 * 328 * Throws: GException on failure. 329 */ 330 public bool forwardFinish(AsyncResultIF result, out TextIter matchStart, out TextIter matchEnd, out bool hasWrappedAround) 331 { 332 GtkTextIter* outmatchStart = sliceNew!GtkTextIter(); 333 GtkTextIter* outmatchEnd = sliceNew!GtkTextIter(); 334 int outhasWrappedAround; 335 GError* err = null; 336 337 auto __p = gtk_source_search_context_forward_finish(gtkSourceSearchContext, (result is null) ? null : result.getAsyncResultStruct(), outmatchStart, outmatchEnd, &outhasWrappedAround, &err) != 0; 338 339 if (err !is null) 340 { 341 throw new GException( new ErrorG(err) ); 342 } 343 344 matchStart = ObjectG.getDObject!(TextIter)(outmatchStart, true); 345 matchEnd = ObjectG.getDObject!(TextIter)(outmatchEnd, true); 346 hasWrappedAround = (outhasWrappedAround == 1); 347 348 return __p; 349 } 350 351 /** 352 * Returns: the associated buffer. 353 */ 354 public Buffer getBuffer() 355 { 356 auto __p = gtk_source_search_context_get_buffer(gtkSourceSearchContext); 357 358 if(__p is null) 359 { 360 return null; 361 } 362 363 return ObjectG.getDObject!(Buffer)(cast(GtkSourceBuffer*) __p); 364 } 365 366 /** 367 * Returns: whether to highlight the search occurrences. 368 */ 369 public bool getHighlight() 370 { 371 return gtk_source_search_context_get_highlight(gtkSourceSearchContext) != 0; 372 } 373 374 /** 375 * Returns: the #GtkSourceStyle to apply on search matches. 376 */ 377 public Style getMatchStyle() 378 { 379 auto __p = gtk_source_search_context_get_match_style(gtkSourceSearchContext); 380 381 if(__p is null) 382 { 383 return null; 384 } 385 386 return ObjectG.getDObject!(Style)(cast(GtkSourceStyle*) __p); 387 } 388 389 /** 390 * Gets the position of a search occurrence. 391 * 392 * If the buffer is not already fully scanned, the position may be unknown, 393 * and -1 is returned. If 0 is returned, it means that this part of the buffer 394 * has already been scanned, and that @match_start and @match_end don't delimit an occurrence. 395 * 396 * Params: 397 * matchStart = the start of the occurrence. 398 * matchEnd = the end of the occurrence. 399 * 400 * Returns: the position of the search occurrence. The first occurrence has the 401 * position 1 (not 0). Returns 0 if @match_start and @match_end don't delimit 402 * an occurrence. Returns -1 if the position is not yet known. 403 */ 404 public int getOccurrencePosition(TextIter matchStart, TextIter matchEnd) 405 { 406 return gtk_source_search_context_get_occurrence_position(gtkSourceSearchContext, (matchStart is null) ? null : matchStart.getTextIterStruct(), (matchEnd is null) ? null : matchEnd.getTextIterStruct()); 407 } 408 409 /** 410 * Gets the total number of search occurrences. 411 * 412 * If the buffer is not already fully scanned, the total number of occurrences is 413 * unknown, and -1 is returned. 414 * 415 * Returns: the total number of search occurrences, or -1 if unknown. 416 */ 417 public int getOccurrencesCount() 418 { 419 return gtk_source_search_context_get_occurrences_count(gtkSourceSearchContext); 420 } 421 422 /** 423 * Regular expression patterns must follow certain rules. If 424 * [property@SearchSettings:search-text] breaks a rule, the error can be 425 * retrieved with this function. 426 * 427 * The error domain is [enum@GLib.RegexError]. 428 * 429 * Free the return value with [method@GLib.Error.free]. 430 * 431 * Returns: the #GError, or %NULL if the 432 * pattern is valid. 433 */ 434 public ErrorG getRegexError() 435 { 436 auto __p = gtk_source_search_context_get_regex_error(gtkSourceSearchContext); 437 438 if(__p is null) 439 { 440 return null; 441 } 442 443 return new ErrorG(cast(GError*) __p, true); 444 } 445 446 /** 447 * Returns: the search settings. 448 */ 449 public SearchSettings getSettings() 450 { 451 auto __p = gtk_source_search_context_get_settings(gtkSourceSearchContext); 452 453 if(__p is null) 454 { 455 return null; 456 } 457 458 return ObjectG.getDObject!(SearchSettings)(cast(GtkSourceSearchSettings*) __p); 459 } 460 461 /** 462 * Replaces a search match by another text. If @match_start and @match_end 463 * doesn't correspond to a search match, %FALSE is returned. 464 * 465 * @match_start and @match_end iters are revalidated to point to the replacement 466 * text boundaries. 467 * 468 * For a regular expression replacement, you can check if @replace is valid by 469 * calling [func@GLib.Regex.check_replacement]. The @replace text can contain 470 * backreferences. 471 * 472 * Params: 473 * matchStart = the start of the match to replace. 474 * matchEnd = the end of the match to replace. 475 * replace = the replacement text. 476 * replaceLength = the length of @replace in bytes, or -1. 477 * 478 * Returns: whether the match has been replaced. 479 * 480 * Throws: GException on failure. 481 */ 482 public bool replace(TextIter matchStart, TextIter matchEnd, string replace, int replaceLength) 483 { 484 GError* err = null; 485 486 auto __p = gtk_source_search_context_replace(gtkSourceSearchContext, (matchStart is null) ? null : matchStart.getTextIterStruct(), (matchEnd is null) ? null : matchEnd.getTextIterStruct(), Str.toStringz(replace), replaceLength, &err) != 0; 487 488 if (err !is null) 489 { 490 throw new GException( new ErrorG(err) ); 491 } 492 493 return __p; 494 } 495 496 /** 497 * Replaces all search matches by another text. 498 * 499 * It is a synchronous function, so it can block the user interface. 500 * 501 * For a regular expression replacement, you can check if @replace is valid by 502 * calling [func@GLib.Regex.check_replacement]. The @replace text can contain 503 * backreferences. 504 * 505 * Params: 506 * replace = the replacement text. 507 * replaceLength = the length of @replace in bytes, or -1. 508 * 509 * Returns: the number of replaced matches. 510 * 511 * Throws: GException on failure. 512 */ 513 public uint replaceAll(string replace, int replaceLength) 514 { 515 GError* err = null; 516 517 auto __p = gtk_source_search_context_replace_all(gtkSourceSearchContext, Str.toStringz(replace), replaceLength, &err); 518 519 if (err !is null) 520 { 521 throw new GException( new ErrorG(err) ); 522 } 523 524 return __p; 525 } 526 527 /** 528 * Enables or disables the search occurrences highlighting. 529 * 530 * Params: 531 * highlight = the setting. 532 */ 533 public void setHighlight(bool highlight) 534 { 535 gtk_source_search_context_set_highlight(gtkSourceSearchContext, highlight); 536 } 537 538 /** 539 * Set the style to apply on search matches. 540 * 541 * If @match_style is %NULL, default theme's scheme 'match-style' will be used. 542 * To enable or disable the search highlighting, use [method@SearchContext.set_highlight]. 543 * 544 * Params: 545 * matchStyle = a #GtkSourceStyle, or %NULL. 546 */ 547 public void setMatchStyle(Style matchStyle) 548 { 549 gtk_source_search_context_set_match_style(gtkSourceSearchContext, (matchStyle is null) ? null : matchStyle.getStyleStruct()); 550 } 551 }